home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / os / sprite.X11R3 / RCS / connect.c,v < prev    next >
Encoding:
Text File  |  1989-10-26  |  55.0 KB  |  2,265 lines

  1. head     1.20;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.20
  10. date     89.10.23.18.21.54;  author tve;  state Exp;
  11. branches ;
  12. next     1.19;
  13.  
  14. 1.19
  15. date     89.10.23.17.43.49;  author tve;  state Exp;
  16. branches ;
  17. next     1.18;
  18.  
  19. 1.18
  20. date     88.09.16.10.57.22;  author ouster;  state Exp;
  21. branches ;
  22. next     1.17;
  23.  
  24. 1.17
  25. date     88.09.08.18.15.32;  author ouster;  state Exp;
  26. branches ;
  27. next     1.16;
  28.  
  29. 1.16
  30. date     88.08.27.11.42.10;  author deboor;  state Exp;
  31. branches ;
  32. next     1.15;
  33.  
  34. 1.15
  35. date     88.01.27.17.03.30;  author deboor;  state Exp;
  36. branches ;
  37. next     1.14;
  38.  
  39. 1.14
  40. date     87.11.29.19.48.34;  author deboor;  state Exp;
  41. branches ;
  42. next     1.13;
  43.  
  44. 1.13
  45. date     87.11.01.20.18.53;  author deboor;  state Exp;
  46. branches ;
  47. next     1.12;
  48.  
  49. 1.12
  50. date     87.09.08.13.05.23;  author deboor;  state Exp;
  51. branches ;
  52. next     1.11;
  53.  
  54. 1.11
  55. date     87.08.21.20.41.50;  author deboor;  state Exp;
  56. branches ;
  57. next     1.10;
  58.  
  59. 1.10
  60. date     87.08.21.20.29.27;  author deboor;  state Exp;
  61. branches ;
  62. next     1.9;
  63.  
  64. 1.9
  65. date     87.07.07.18.16.52;  author deboor;  state Exp;
  66. branches ;
  67. next     1.8;
  68.  
  69. 1.8
  70. date     87.06.30.19.12.25;  author deboor;  state Exp;
  71. branches ;
  72. next     1.7;
  73.  
  74. 1.7
  75. date     87.06.24.12.51.17;  author deboor;  state Exp;
  76. branches ;
  77. next     1.6;
  78.  
  79. 1.6
  80. date     87.06.23.13.30.21;  author deboor;  state Exp;
  81. branches ;
  82. next     1.5;
  83.  
  84. 1.5
  85. date     87.06.20.19.58.07;  author deboor;  state Exp;
  86. branches ;
  87. next     1.4;
  88.  
  89. 1.4
  90. date     87.06.16.12.22.57;  author deboor;  state Exp;
  91. branches ;
  92. next     1.3;
  93.  
  94. 1.3
  95. date     87.06.13.11.21.46;  author deboor;  state Exp;
  96. branches ;
  97. next     1.2;
  98.  
  99. 1.2
  100. date     87.06.11.18.41.34;  author deboor;  state Exp;
  101. branches ;
  102. next     1.1;
  103.  
  104. 1.1
  105. date     87.06.11.17.47.03;  author deboor;  state Exp;
  106. branches ;
  107. next     ;
  108.  
  109.  
  110. desc
  111. @functions for manipulating connections to clients
  112. @
  113.  
  114.  
  115. 1.20
  116. log
  117. @error stream goes to /tmp/HOST:DISPLAY.X11R3
  118. @
  119. text
  120. @/*-
  121.  * connect.c --
  122.  *    Functions to handle generic connections and their I/O.
  123.  *
  124.  * Copyright (c) 1987 by the Regents of the University of California
  125.  *
  126.  * Permission to use, copy, modify, and distribute this
  127.  * software and its documentation for any purpose and without
  128.  * fee is hereby granted, provided that the above copyright
  129.  * notice appear in all copies.  The University of California
  130.  * makes no representations about the suitability of this
  131.  * software for any purpose.  It is provided "as is" without
  132.  * express or implied warranty.
  133.  *
  134.  *
  135.  */
  136. #ifndef lint
  137. static char rcsid[] =
  138. "$Header: /mic/X11R3/src/cmds/Xsp/os/sprite/RCS/connect.c,v 1.19 89/10/23 17:43:49 tve Exp Locker: tve $ SPRITE (Berkeley)";
  139. #endif lint
  140.  
  141. #include    "Xproto.h"
  142. #include    "spriteos.h"
  143. #include    "dix.h"
  144. #include    "osstruct.h"
  145.  
  146. #include    <bit.h>
  147. #include    <signal.h>
  148. #include    <stdio.h>
  149. #include    <string.h>
  150.  
  151. /*-
  152.  *-----------------------------------------------------------------------
  153.  * CreateWellKnownSockets --
  154.  *    Create listening points via which we can accept connections from
  155.  *    clients. It also finishes off the initialization needed by the
  156.  *    OS layer.
  157.  *
  158.  * Results:
  159.  *    None.
  160.  *
  161.  * Side Effects:
  162.  *    PseudoDevice is set to the streamID of the server's pseudo device.
  163.  *    All the select masks are allocated and initialized.
  164.  *    NumActiveStreams is initialized. Vectors interrupts to HangUp.
  165.  *
  166.  *-----------------------------------------------------------------------
  167.  */
  168. void
  169. CreateWellKnownSockets()
  170. {
  171.     char          errorfile[50];    /* Path to error file */
  172.     int              whichbyte;        /* Used to figure out whether this machine
  173.                      * is LSB or MSB */
  174.     void      HangUp();
  175.     int              Reset();
  176.     struct      sigvec irq;
  177.     int              oldPermMask;        /* Previous permission mask */
  178.     char          hostname[64];
  179.     char          *cp;
  180.  
  181.     gethostname(hostname, sizeof(hostname));
  182.     cp = index(hostname, '.');
  183.     if (cp != (char *)NULL) {
  184.     *cp = '\0';
  185.     }
  186.  
  187.     oldPermMask = umask(0);
  188.  
  189.     sprintf (errorfile, "/tmp/%s:%s.X11R3", hostname, display);
  190.     fclose (stderr);
  191.     fopen (errorfile, "w+");        /* Will go to stderr. */
  192.  
  193.     (void) umask(oldPermMask);
  194.  
  195.  
  196. #ifdef TCPCONN
  197.     TCP_Init();
  198.     NumActiveStreams = max(NumActiveStreams, TCP_Conn+1);
  199. #endif TCPCONN
  200.  
  201.     Pdev_Init(hostname);
  202.     NumActiveStreams = max(NumActiveStreams, Pdev_Conn+1);
  203.     
  204.     /*
  205.      * Allocate all the global bit masks. I'd prefer to do such things
  206.      * in OsInit, but they leave me little choice, since this function
  207.      * is called after OsInit...
  208.      */
  209.     Bit_Alloc (NumActiveStreams, AllStreamsMask);
  210.     Bit_Alloc (NumActiveStreams, LastSelectMask);
  211.     Bit_Alloc (NumActiveStreams, EnabledDevicesMask);
  212.     Bit_Alloc (NumActiveStreams, ClientsWithInputMask);
  213.     Bit_Alloc (NumActiveStreams, AllClientsMask);
  214.     Bit_Alloc (NumActiveStreams, SavedAllClientsMask);
  215.     Bit_Alloc (NumActiveStreams, SavedAllStreamsMask);
  216.  
  217. #ifdef TCPCONN
  218.     Bit_Set (TCP_Conn, AllStreamsMask);
  219. #endif TCPCONN
  220.     Bit_Set (Pdev_Conn, AllStreamsMask);
  221.  
  222.     whichbyte = 1;
  223.  
  224.     if (*(char *)&whichbyte) {
  225.     whichByteIsFirst = 'l';
  226.     } else {
  227.     whichByteIsFirst = 'B';
  228.     }
  229.  
  230.     irq.sv_handler = /*(int (*)())*/ HangUp;
  231.     irq.sv_mask = 0;
  232.     irq.sv_onstack = 0;
  233.     sigvec(SIGINT, &irq, (struct sigvec *) 0);
  234.     sigvec(SIGTERM, &irq, (struct sigvec *) 0);
  235. }
  236.  
  237.     
  238. /*-
  239.  *-----------------------------------------------------------------------
  240.  * CloseDownConnection --
  241.  *    Some client is being booted. Free up its connection resources.
  242.  *
  243.  * Results:
  244.  *    None.
  245.  *
  246.  * Side Effects:
  247.  *    The pseudo-device streams are closed and the private data marked
  248.  *    inactive. The stream is removed from these masks:
  249.  *        AllStreamsMask, SavedAllStreamsMask, AllClientsMask,
  250.  *        SavedAllClientsMask, ClientsWithInputMask
  251.  *
  252.  *-----------------------------------------------------------------------
  253.  */
  254. CloseDownConnection (client)
  255.     ClientPtr    client;        /* Client whose connection should
  256.                  * be closed */
  257. {
  258.     register ClntPrivPtr    pPriv;
  259.     register int          i;
  260.  
  261.     pPriv = (ClntPrivPtr) client->osPrivate;
  262.  
  263.     if (DBG(CONN)) {
  264.     ErrorF ("CloseDownConnection: client %d being booted\n", client->index);
  265.     }
  266.  
  267.     (* pPriv->closeProc) (pPriv);
  268.  
  269.     Bit_Free (pPriv->mask);
  270.     Bit_Free (pPriv->ready);
  271.     free ((char *) pPriv);
  272. }
  273.  
  274. /*-
  275.  *-----------------------------------------------------------------------
  276.  * AddEnabledDevice --
  277.  *    Add another device to keep track of.
  278.  *
  279.  * Results:
  280.  *    None.
  281.  *
  282.  * Side Effects:
  283.  *    The select masks may be expanded. EnabledDevicesMask will be
  284.  *    altered.
  285.  *
  286.  *-----------------------------------------------------------------------
  287.  */
  288. AddEnabledDevice (streamID)
  289.     int        streamID;
  290. {
  291.     ExpandMasks (0, streamID);
  292.  
  293.     Bit_Set (streamID, AllStreamsMask);
  294.     Bit_Set (streamID, SavedAllStreamsMask);
  295.     Bit_Set (streamID, EnabledDevicesMask);
  296. }
  297.  
  298. /*-
  299.  *-----------------------------------------------------------------------
  300.  * RemoveEnabledDevice --
  301.  *    Stop paying attention to some device.
  302.  *
  303.  * Results:
  304.  *
  305.  * Side Effects:
  306.  *
  307.  *-----------------------------------------------------------------------
  308.  */
  309. RemoveEnabledDevice (streamID)
  310.     int        streamID;
  311. {
  312.     Bit_Clear (streamID, AllStreamsMask);
  313.     Bit_Clear (streamID, SavedAllStreamsMask);
  314.     Bit_Clear (streamID, EnabledDevicesMask);
  315. }
  316.  
  317. /*-
  318.  *-----------------------------------------------------------------------
  319.  * OnlyListenToOneClient --
  320.  *    Only pay attention to requests from one client. We continue to
  321.  *    accept new connections, of course, but only take protocol requests
  322.  *    from this single connection.
  323.  *    Once this is done, GrabDone will be set TRUE and and changes to
  324.  *    AllStreamsMask and AllClientsMask should be done to their Saved
  325.  *    copies.
  326.  *    Devices are unaffected, of course.
  327.  *
  328.  * Results:
  329.  *    None.
  330.  *
  331.  * Side Effects:
  332.  *    AllStreamsMask and AllClientsMask are copied into SavedAllStreamsMask
  333.  *    and SavedAllClientsMask, respectively, and have all the other
  334.  *    client bits removed from them.
  335.  *    ClientsWithInputMask has all other clients's bits removed from it.
  336.  *    GrabDone is set TRUE.
  337.  *
  338.  *-----------------------------------------------------------------------
  339.  */
  340. OnlyListenToOneClient (client)
  341.     ClientPtr        client;
  342. {
  343.     ClntPrivPtr      pPriv = (ClntPrivPtr) client->osPrivate;
  344.     int              *tempMask;
  345.  
  346.     /*
  347.      * First take everyone but the given client out of the ClientsWithInputMask
  348.      * We have to allocate a new mask b/c there's no guarantee that the
  349.      * private mask will be as wide as the regular masks, though it
  350.      * usually is.
  351.      */
  352.     Bit_Alloc (NumActiveStreams, tempMask);
  353.     (void) Bit_Copy (pPriv->maskWidth, pPriv->mask, tempMask);
  354.     (void) Bit_Intersect (NumActiveStreams, tempMask,
  355.               ClientsWithInputMask, ClientsWithInputMask);
  356.  
  357.     if (DBG(CONN)) {
  358.     ErrorF("Server grabbed by client %d\n", client->index);
  359.     }
  360.     if (!GrabDone) {
  361.     /*
  362.      * If a grab has not already been done, duplicate the AllStreams
  363.      * and AllClients masks.
  364.      */
  365.       
  366.     Bit_Copy (NumActiveStreams, AllStreamsMask, SavedAllStreamsMask);
  367.     Bit_Copy (NumActiveStreams, AllClientsMask, SavedAllClientsMask);
  368.  
  369.     }
  370.     (void) Bit_Union (NumActiveStreams, tempMask, EnabledDevicesMask,
  371.               AllStreamsMask);
  372.     Bit_Copy (NumActiveStreams, pPriv->mask, AllClientsMask);
  373.     Bit_Free (tempMask);
  374.  
  375.     GrabDone = TRUE;
  376.     grabbingClient = client;
  377. }
  378.     
  379. /*-
  380.  *-----------------------------------------------------------------------
  381.  * ListenToAllClients --
  382.  *    Undo a grab: start paying attention to cries from other clients.
  383.  *
  384.  * Results:
  385.  *    None.
  386.  *
  387.  * Side Effects:
  388.  *    GrabDone is set FALSE and the AllClients and AllStreams masks are
  389.  *    restored from their Saved counterparts.
  390.  *
  391.  *-----------------------------------------------------------------------
  392.  */
  393. ListenToAllClients()
  394. {
  395.     if (GrabDone) {
  396.     if (DBG(CONN)) {
  397.         ErrorF ("Server ungrabbed again\n");
  398.     }
  399.     Bit_Copy (NumActiveStreams, SavedAllStreamsMask, AllStreamsMask);
  400.     Bit_Copy (NumActiveStreams, SavedAllClientsMask, AllClientsMask);
  401.     GrabDone = FALSE;
  402.     }
  403. }
  404.  
  405. /*-
  406.  *-----------------------------------------------------------------------
  407.  * ReadRequestFromClient --
  408.  *    Read a single request from a client. This is just a front-end that
  409.  *    passes the buck to the connection-specific function...
  410.  *
  411.  * Results:
  412.  *    What he said.
  413.  *
  414.  * Side Effects:
  415.  *    Not here..
  416.  *
  417.  *-----------------------------------------------------------------------
  418.  */
  419. char *
  420. ReadRequestFromClient (client, pStatus, oldbuf)
  421.     ClientPtr          client;        /* Client with input */
  422.     int                  *pStatus;   /* Result of read:
  423.                      * >0 -- number of bytes in the request
  424.                      * 0 -- not all the request is there
  425.                      * <0 -- indicates an error */
  426.     char              *oldbuf;    /* The previous buffer (IGNORED) */
  427. {
  428.     ClntPrivPtr          pPriv;        /* Private data for the client */
  429.  
  430.     pPriv = (ClntPrivPtr) client->osPrivate;
  431.  
  432.     oldbuf = (* pPriv->readProc) (pPriv, pStatus, oldbuf);
  433.     if (*pStatus > 0) {
  434.     SchedPacket(client);
  435.     }
  436.     return (oldbuf);
  437. }
  438.  
  439. /*-
  440.  *-----------------------------------------------------------------------
  441.  * WriteToClient --
  442.  *    Function to write stuff to a client. Just a front-end for the
  443.  *    connection-specific stuff.
  444.  *
  445.  * Results:
  446.  *    What he said.
  447.  *
  448.  * Side Effects:
  449.  *    Elsewhere.
  450.  *
  451.  *-----------------------------------------------------------------------
  452.  */
  453. int
  454. WriteToClient (client, numBytes, buf)
  455.     ClientPtr          client;        /* Client to receive the data */
  456.     int                  numBytes;   /* Number of bytes to transmit */
  457.     char              *buf;        /* Buffer to send */
  458. {
  459.     ClntPrivPtr          pPriv;        /* OS-private data */
  460.  
  461.     pPriv = (ClntPrivPtr) client->osPrivate;
  462.  
  463.     return ((* pPriv->writeProc) (pPriv, numBytes, buf));
  464. }
  465.  
  466. /*-
  467.  *-----------------------------------------------------------------------
  468.  * ExpandMasks --
  469.  *    Given a newly-opened stream, expand all the thousands of
  470.  *    select masks to encompass that stream. This includes the private
  471.  *    mask for the client.
  472.  *
  473.  * Results:
  474.  *    None.
  475.  *
  476.  * Side Effects:
  477.  *    The masks will be moved and the old ones freed..
  478.  *
  479.  *-----------------------------------------------------------------------
  480.  */
  481. void
  482. ExpandMasks (pPriv, newStream)
  483.     ClntPrivPtr      pPriv;        /* Private data for client.
  484.                  * Should be 0 if it wasn't opened for a client
  485.                  * (e.g. it's for a device) */
  486.     int              newStream;    /* The new stream's ID number */
  487. {
  488.     if (newStream >= NumActiveStreams) {
  489.     register int newNumStreams = newStream + 1;
  490.     
  491.     AllStreamsMask =        Bit_Expand (newNumStreams, NumActiveStreams,
  492.                         AllStreamsMask);
  493.     LastSelectMask =        Bit_Expand (newNumStreams, NumActiveStreams,
  494.                         LastSelectMask);
  495.     EnabledDevicesMask =     Bit_Expand (newNumStreams, NumActiveStreams,
  496.                         EnabledDevicesMask);
  497.     ClientsWithInputMask =     Bit_Expand (newNumStreams, NumActiveStreams,
  498.                         ClientsWithInputMask);
  499.     AllClientsMask =        Bit_Expand (newNumStreams, NumActiveStreams,
  500.                         AllClientsMask);
  501.     SavedAllClientsMask =    Bit_Expand (newNumStreams, NumActiveStreams,
  502.                         SavedAllClientsMask);
  503.     SavedAllStreamsMask =    Bit_Expand (newNumStreams, NumActiveStreams,
  504.                         SavedAllStreamsMask);
  505.     NumActiveStreams = newNumStreams;
  506.     }
  507.  
  508.     /*
  509.      * We need to also expand the private mask for the client to
  510.      * encompass the new stream.
  511.      */
  512.     if (pPriv) {
  513.     if (newStream >= pPriv->maskWidth) {
  514.         pPriv->mask = Bit_Expand (newStream+1, pPriv->maskWidth,
  515.                       pPriv->mask);
  516.         pPriv->ready = Bit_Expand (newStream+1, pPriv->maskWidth,
  517.                        pPriv->ready);
  518.         pPriv->maskWidth = newStream + 1;
  519.     }
  520.     Bit_Set (newStream, pPriv->mask);
  521.     }
  522. }
  523. @
  524.  
  525.  
  526. 1.19
  527. log
  528. @changes for X11R3
  529. @
  530. text
  531. @d19 1
  532. a19 1
  533. "$Header: /mic/X11R3/src/cmds/Xsprite/os/sprite/RCS/connect.c,v 1.18 88/09/16 10:57:22 ouster Exp Locker: tve $ SPRITE (Berkeley)";
  534. d70 1
  535. a70 1
  536.     sprintf (errorfile, "/tmp/%s.X%smsgs", hostname, display);
  537. @
  538.  
  539.  
  540. 1.18
  541. log
  542. @In changing to new C library goofed umask arguments.
  543. @
  544. text
  545. @d19 1
  546. a19 1
  547. "$Header: connect.c,v 1.17 88/09/08 18:15:32 ouster Exp $ SPRITE (Berkeley)";
  548. d55 1
  549. a55 1
  550.     int              HangUp();
  551. d111 1
  552. a111 1
  553.     irq.sv_handler = (int (*)()) HangUp;
  554. @
  555.  
  556.  
  557. 1.17
  558. log
  559. @Intermediate check-in while converting to new C library.
  560. @
  561. text
  562. @d19 1
  563. a19 1
  564. "$Header: connect.c,v 1.16 88/08/27 11:42:10 deboor Exp $ SPRITE (Berkeley)";
  565. d68 1
  566. a68 1
  567.     oldPermMask = umask(0777);
  568. @
  569.  
  570.  
  571. 1.16
  572. log
  573. @Added OLDPDEV defines
  574. @
  575. text
  576. @d19 1
  577. a19 1
  578. "$Header: connect.c,v 1.15 88/01/27 17:03:30 deboor Exp $ SPRITE (Berkeley)";
  579. d27 5
  580. d57 1
  581. a57 1
  582.     Sig_Action      irq;                /* Action when interrupted */
  583. d62 2
  584. a63 2
  585.     Sys_GetHostName (sizeof(hostname), hostname);
  586.     cp = String_FindChar(hostname, '.');
  587. a66 2
  588.     
  589.     (void) Fs_SetDefPerm (0777, &oldPermMask);
  590. d68 1
  591. a68 3
  592.     Io_PrintString (errorfile, "/tmp/%s.X%smsgs", hostname, display);
  593.     Io_Close (io_StdErr);
  594.     io_StdErr = Io_Open (errorfile, "w+");
  595. d70 3
  596. a72 1
  597.     (void) Fs_SetDefPerm (oldPermMask, &oldPermMask);
  598. d74 1
  599. a75 4
  600. #ifdef OLDPDEV
  601.     Pdev_Init(hostname);
  602.     NumActiveStreams = Pdev_Conn + 1;
  603. #endif OLDPDEV
  604. d82 2
  605. a83 4
  606. #ifdef NEWPDEV
  607.     NewPdev_Init(hostname);
  608.     NumActiveStreams = max(NumActiveStreams, NewPdev_Conn+1);
  609. #endif NEWPDEV
  610. a97 3
  611. #ifdef OLDPDEV
  612.     Bit_Set (Pdev_Conn, AllStreamsMask);
  613. #endif OLDPDEV    
  614. d101 1
  615. a101 3
  616. #ifdef NEWPDEV
  617.     Bit_Set (NewPdev_Conn, AllStreamsMask);
  618. #endif NEWPDEV
  619. d111 5
  620. a115 8
  621.     irq.action = SIG_HANDLE_ACTION;
  622.     irq.handler = HangUp;
  623.     irq.sigHoldMask = 0;
  624.  
  625.     Sig_SetAction (SIG_INTERRUPT, &irq, (Sig_Action *)0);
  626.  
  627.     irq.handler = HangUp;
  628.     Sig_SetAction (SIG_TERM, &irq, (Sig_Action *)0);
  629. d152 1
  630. a152 1
  631.     Mem_Free (pPriv);
  632. @
  633.  
  634.  
  635. 1.15
  636. log
  637. @Added trimming of domain name from hostname
  638. @
  639. text
  640. @d19 1
  641. a19 1
  642. "$Header: connect.c,v 1.14 87/11/29 19:48:34 deboor Exp $ SPRITE (Berkeley)";
  643. d72 1
  644. d75 1
  645. d100 1
  646. d102 1
  647. d124 1
  648. a124 1
  649.     irq.handler = Reset;
  650. @
  651.  
  652.  
  653. 1.14
  654. log
  655. @Added support for new pseudo-devices and conditional debugging
  656. @
  657. text
  658. @d19 1
  659. a19 1
  660. "$Header: connect.c,v 1.13 87/11/01 20:18:53 deboor Exp $ SPRITE (Berkeley)";
  661. d55 1
  662. d58 5
  663. @
  664.  
  665.  
  666. 1.13
  667. log
  668. @Generalized connection interface to allow multiple types of connections.
  669. For now, this is TCP and Pdev.
  670. @
  671. text
  672. @d19 1
  673. a19 1
  674. "$Header: connect.c,v 1.12 87/09/08 13:05:23 deboor Exp $ SPRITE (Berkeley)";
  675. d71 1
  676. a71 1
  677.     NumActiveStreams = max(NumActiveStreams, TCP_Conn);
  678. d73 5
  679. d96 3
  680. d144 3
  681. a146 1
  682.     ErrorF ("CloseDownConnection: client %d being booted\n", client->index);
  683. d238 3
  684. a240 1
  685.     ErrorF("Server grabbed by client %d\n", client->index);
  686. d277 3
  687. a279 1
  688.     ErrorF ("Server ungrabbed again\n");
  689. d314 3
  690. a316 1
  691.     SchedPacket(client);
  692. @
  693.  
  694.  
  695. 1.12
  696. log
  697. @Adapted to new pseudo-device stuff
  698. @
  699. text
  700. @d3 1
  701. a3 1
  702.  *    Functions to handle connections.
  703. d19 1
  704. a19 1
  705. "$Header: connect.c,v 1.11 87/08/21 20:41:50 deboor Exp $ SPRITE (Berkeley)";
  706. a26 11
  707. /*
  708.  * Template for the pseudo-device through which we communicate. Given to
  709.  * one of the Io_Print functions and expects two arguments: the name of the
  710.  * local host and the display number we're using.
  711.  */
  712. #define    DEVICE_TEMPLATE    "/hosts/%s/X%s"
  713.  
  714. #define REASONABLE_TIME        5
  715.  
  716. int    PseudoDevice;    /* Stream open to pseudodevice */
  717.  
  718. a47 1
  719.     char          deviceName[100];  /* Path to pseudo-device */
  720. a49 2
  721.     int              oldPermMask;        /* Previous permission mask */
  722.     Sig_Action      irq;                /* Action when interrupted */
  723. d52 3
  724. a54 1
  725.     char          hostname[64];        /* Our hostname */
  726. a55 4
  727.     /*
  728.      * Create the pseudo-device, making sure it's readable and writeable
  729.      * by everyone.
  730.      */
  731. d57 1
  732. a58 10
  733.     Io_PrintString (deviceName, DEVICE_TEMPLATE, hostname, display);
  734.     if ((Fs_SetDefPerm (0777, &oldPermMask) != SUCCESS) ||
  735.         (Fs_Open (deviceName,
  736.           FS_NON_BLOCKING | FS_CREATE | FS_READ | FS_MASTER,
  737.           0666,
  738.           &PseudoDevice) != SUCCESS)) {
  739.               Error (deviceName);
  740.               FatalError ("Could not open pseudo-device %s",
  741.                   deviceName);
  742.     }
  743. d65 8
  744. a72 1
  745.     NumActiveStreams = PseudoDevice + 1;
  746. d87 4
  747. a90 1
  748.     Bit_Set (PseudoDevice, AllStreamsMask);
  749. a109 27
  750. /*-
  751.  *-----------------------------------------------------------------------
  752.  * ReadConn --
  753.  *    Read a connection for an exact amount of data. If the client
  754.  *    doesn't write the data within a reasonable time, or doesn't
  755.  *    write enough data, an error is returned.
  756.  *
  757.  * Results:
  758.  *      SUCCESS or an error status.
  759.  *
  760.  * Side Effects:
  761.  *    The buffer has data read into it.
  762.  *
  763.  *-----------------------------------------------------------------------
  764.  */
  765. static ReturnStatus
  766. ReadConn (streamID, selMask, bufSize, bufPtr)
  767.     int                  streamID;   /* Stream to read */
  768.     int                  *selMask;   /* Pre-allocate select mask (not set) */
  769.     int                  bufSize;    /* Amount of data needed */
  770.     char              *bufPtr;    /* Buffer in which to store data */
  771. {
  772.     Pdev_Request    pdev;
  773.     Pdev_EasyReply    reply;
  774.     SpriteTime          timeout;
  775.     int                  numReady;
  776.     int                  numBytes;
  777. a110 48
  778.  
  779.     Bit_Set (streamID, selMask);
  780.     timeout.seconds = REASONABLE_TIME;
  781.     timeout.microseconds = 0;
  782.  
  783.     if ((Fs_Select (streamID + 1, &timeout, selMask, (int *)0, (int *)0,
  784.            &numReady) != SUCCESS) ||
  785.     (numReady != 1)) {
  786.         if (numReady == 0) {
  787.         return (FS_TIMEOUT);
  788.         } else {
  789.         return (stat_LastError);
  790.         }
  791.     }
  792.     
  793.     if (Fs_Read (streamID, sizeof(pdev), &pdev, &numBytes) != SUCCESS) {
  794.     Error ("ReadConn");
  795.     return (FAILURE);
  796.     }
  797.     if (pdev.magic != PDEV_REQUEST_MAGIC) {
  798.     ErrorF ("Request magic numbers don't match\n");
  799.     return (FAILURE);
  800.     }
  801.     if (pdev.operation != PDEV_WRITE) {
  802.     ErrorF ("ReadConn: operation not a write\n");
  803.     return (FAILURE);
  804.     }
  805.  
  806.     /*
  807.      * However many bytes the client wrote, we will read them all (or we'll
  808.      * close down the connection...)
  809.      */
  810.     reply.replySize = sizeof(int);
  811.     reply.data = pdev.requestSize;
  812.     reply.status = SUCCESS;
  813.     reply.selectBits = FS_WRITABLE;
  814.     reply.magic = PDEV_REPLY_MAGIC;
  815.     if (Fs_Write (streamID, sizeof(reply), &reply, &numBytes) != SUCCESS) {
  816.     return (FAILURE);
  817.     }
  818.     
  819.     if ((Fs_Read (streamID, bufSize, bufPtr, &numBytes) != SUCCESS) ||
  820.     (numBytes != bufSize)){
  821.         return (FAILURE);
  822.     }
  823.     return (SUCCESS);
  824. }
  825.  
  826. a112 506
  827.  * ClientAuthorized --
  828.  *    See if a client is authorized to use this server.
  829.  *
  830.  *        Sent by the client at connection setup:
  831.  *                typedef struct _xConnClientPrefix {
  832.  *                   CARD8    byteOrder;
  833.  *                   BYTE    pad;
  834.  *                   CARD16    majorVersion, minorVersion;
  835.  *                   CARD16    nbytesAuthProto;    
  836.  *                   CARD16    nbytesAuthString;   
  837.  *                 } xConnClientPrefix;
  838.  *    followed by the bytes of the AuthProto and the AuthString.
  839.  *
  840.  *         It is hoped that eventually one protocol will be agreed upon.  In the
  841.  *        mean time, a server that implements a different protocol than the
  842.  *        client expects, or a server that only implements the host-based
  843.  *        mechanism, will simply ignore this information.
  844.  *
  845.  * Results:
  846.  *    Returns TRUE if the client may use the server.
  847.  *    *pswapped is set TRUE if the client uses a different byte-order
  848.  *    than we.
  849.  *
  850.  * Side Effects:
  851.  *    *pswapped is alterred.
  852.  *
  853.  *-----------------------------------------------------------------------
  854.  */
  855. /*ARGSUSED*/
  856. static int
  857. ClientAuthorized (conn, pswapped, uid, hostid)
  858.     int                  conn;         /* Stream of connection */
  859.     Bool              *pswapped;  /* Set TRUE if client is byte-swapped */
  860.     int                  uid;          /* User ID of connecting client */
  861.     int                  hostid;        /* Host ID of connecting client */
  862. {
  863.     xConnClientPrefix     xccp;        /* Prefix from client */
  864.     Pdev_Reply      openRep;    /* Reply to OPEN request */
  865.     int                  *selMask;   /* Place for selection mask */
  866.     int                  numBytes;
  867.  
  868.     /*
  869.      * Respond to the open call. This is where access control would come in.
  870.      */
  871.     openRep.magic = PDEV_REPLY_MAGIC;
  872.     openRep.status = SUCCESS;
  873.     openRep.selectBits = FS_WRITABLE | FS_READABLE;
  874.     openRep.replySize = 0;
  875.     (void) Fs_Write (conn, sizeof(openRep), &openRep, &numBytes);
  876.     
  877.     /*
  878.      * Since the client was blocked awaiting our response to the OPEN, we must
  879.      * wait for it to write something to us. If it doesn't write within a
  880.      * decent amount of time, we bitch.
  881.      */
  882.     Bit_Alloc (conn+1, selMask);
  883.  
  884.     if (ReadConn (conn, selMask, sizeof(xccp), &xccp) != SUCCESS) {
  885.     Error ("Reading client prefix");
  886.     return (0);
  887.     }
  888.     
  889.     if (xccp.byteOrder != whichByteIsFirst) {
  890.     ErrorF ("Byte-swapping this client; sounds fun!\n");
  891.     SwapConnClientPrefix (&xccp);
  892.     *pswapped = TRUE;
  893.     } else {
  894.     *pswapped = FALSE;
  895.     }
  896.  
  897.     if ((xccp.majorVersion != X_PROTOCOL) ||
  898.     (xccp.minorVersion != X_PROTOCOL_REVISION)) {
  899.         ErrorF ("Not an alpha release library\n");
  900.         return (0);
  901.     }
  902.     
  903.     /*
  904.      * Discard authorization-protocol string, if any
  905.      */
  906.     if (xccp.nbytesAuthProto != 0) {
  907.     char      *authProto;
  908.  
  909.     authProto = (char *)ALLOCATE_LOCAL(xccp.nbytesAuthProto);
  910.     if (ReadConn(conn, selMask, xccp.nbytesAuthProto,
  911.              authProto) != SUCCESS){
  912.              return (0);
  913.     }
  914.     DEALLOCATE_LOCAL (authProto);
  915.     }
  916.  
  917.     /*
  918.      * And the authorization string, if any
  919.      */
  920.     if (xccp.nbytesAuthString != 0) {
  921.     char      *authString;
  922.  
  923.     authString = (char *)ALLOCATE_LOCAL(xccp.nbytesAuthString);
  924.     if (ReadConn(conn, selMask, xccp.nbytesAuthString,
  925.              authString)!=SUCCESS){
  926.              return (0);
  927.     }
  928.     DEALLOCATE_LOCAL (authString);
  929.     }
  930.  
  931.     return (1);
  932. }
  933.  
  934. /*-
  935.  *-----------------------------------------------------------------------
  936.  * ExpandMasks --
  937.  *    Given a newly-opened stream, expand all the thousands of
  938.  *    select masks to encompass that stream. This includes the private
  939.  *    mask for the client.
  940.  *
  941.  * Results:
  942.  *    None.
  943.  *
  944.  * Side Effects:
  945.  *    The masks will be moved and the old ones freed..
  946.  *
  947.  *-----------------------------------------------------------------------
  948.  */
  949. static void
  950. ExpandMasks (client, newStream)
  951.     ClientPtr      client;       /* The client for which the stream was opened.
  952.                  * Should be 0 if it wasn't opened for a client
  953.                  * (e.g. it's for a device) */
  954.     int              newStream;    /* The new stream's ID number */
  955. {
  956.     ClntPrivPtr      pPriv = (ClntPrivPtr)(client ? client->osPrivate : 0);
  957.     
  958.     if (newStream >= NumActiveStreams) {
  959.     register int newNumStreams = newStream + 1;
  960.     
  961.     AllStreamsMask =        Bit_Expand (newNumStreams, NumActiveStreams,
  962.                         AllStreamsMask);
  963.     LastSelectMask =        Bit_Expand (newNumStreams, NumActiveStreams,
  964.                         LastSelectMask);
  965.     EnabledDevicesMask =     Bit_Expand (newNumStreams, NumActiveStreams,
  966.                         EnabledDevicesMask);
  967.     ClientsWithInputMask =     Bit_Expand (newNumStreams, NumActiveStreams,
  968.                         ClientsWithInputMask);
  969.     AllClientsMask =        Bit_Expand (newNumStreams, NumActiveStreams,
  970.                         AllClientsMask);
  971.     SavedAllClientsMask =    Bit_Expand (newNumStreams, NumActiveStreams,
  972.                         SavedAllClientsMask);
  973.     SavedAllStreamsMask =    Bit_Expand (newNumStreams, NumActiveStreams,
  974.                         SavedAllStreamsMask);
  975.     NumActiveStreams = newNumStreams;
  976.     }
  977.  
  978.     /*
  979.      * We need to also expand the private mask for the client to
  980.      * encompass the new stream.
  981.      */
  982.     if (pPriv) {
  983.     if (newStream >= pPriv->maskWidth) {
  984.         pPriv->mask = Bit_Expand (newStream+1, pPriv->maskWidth,
  985.                       pPriv->mask);
  986.         pPriv->ready = Bit_Expand (newStream+1, pPriv->maskWidth,
  987.                        pPriv->ready);
  988.         pPriv->maskWidth = newStream + 1;
  989.     }
  990.     Bit_Set (newStream, pPriv->mask);
  991.     }
  992. }
  993.  
  994. /*-
  995.  *-----------------------------------------------------------------------
  996.  * ConnectionClosed --
  997.  *    Some connection has been closed for some reason. The private
  998.  *    ClntStreamPtr for the stream is given as the argument. The
  999.  *    stream is closed and, if this stream was the last open one
  1000.  *    for the client, the client is closed down.
  1001.  *
  1002.  * Results:
  1003.  *    Always returns 0.
  1004.  *
  1005.  * Side Effects:
  1006.  *    The client stream is closed and the ClntStreamRec is deallocated.
  1007.  *    The streamID is removed from the two appropriate masks.
  1008.  *
  1009.  *-----------------------------------------------------------------------
  1010.  */
  1011. int
  1012. ConnectionClosed (pStream)
  1013.     ClntStreamPtr pStream;        /* The stream to close */
  1014. {
  1015.     ClntPrivPtr      pPriv;            /* Private data for this stream */
  1016.     LstNode       ln;                /* Node of the pStream in the client's
  1017.                      * Lst of streams */
  1018.     
  1019.     ErrorF ("ConnectionClosed: client %d, stream %d\n", pStream->client->index,
  1020.         pStream->streamID);
  1021.     Fs_Close (pStream->streamID);
  1022.     
  1023.     pPriv = (ClntPrivPtr) pStream->client->osPrivate;
  1024.     
  1025.     ln = Lst_Member (pPriv->streams, (ClientData)pStream);
  1026.     if (ln == NILLNODE) {
  1027.     ErrorF ("ConnectionClosed: stream %d already gone?!\n",
  1028.         pStream->streamID);
  1029.     return (1);
  1030.     }
  1031.     if (ln == pPriv->lastStream) {
  1032.     /*
  1033.      * If this stream was the last stream handled by ReadRequestFromClient,
  1034.      * then we have to shift the focus to the previous one or we're liable
  1035.      * to get screwed when we reference through this deallocated LstNode.
  1036.      * (Note that since the streams list is circular, Lst_Pred will always
  1037.      * give a decent LstNode except when ln is the last node in the list,
  1038.      * in which case the whole thing will be going away soon anyway...)
  1039.      */
  1040.     pPriv->lastStream = Lst_Pred(ln);
  1041.     }
  1042.     if (Lst_Remove (pPriv->streams, ln) != SUCCESS) {
  1043.     FatalError ("Couldn't remove node from private streams list");
  1044.     }
  1045.  
  1046.     ln = Lst_Member (allStreams, (ClientData)pStream);
  1047.     if (Lst_Remove (allStreams, ln) != SUCCESS) {
  1048.     FatalError ("Couldn't remove node from allStreams list");
  1049.     }
  1050.     
  1051.     if (pStream->buffer) {
  1052.     Mem_Free (pStream->buffer);
  1053.     }
  1054.     Bit_Clear (pStream->streamID, pPriv->mask);
  1055.     Bit_Clear (pStream->streamID, ClientsWithInputMask);
  1056.  
  1057.     if (GrabDone) {
  1058.     Bit_Clear (pStream->streamID, SavedAllStreamsMask);
  1059.     Bit_Clear (pStream->streamID, SavedAllClientsMask);
  1060.     } else {
  1061.     Bit_Clear (pStream->streamID, AllStreamsMask);
  1062.     Bit_Clear (pStream->streamID, AllClientsMask);
  1063.     }
  1064.  
  1065.     Mem_Free (pStream);
  1066.     return (0);
  1067. }
  1068.  
  1069. /*-
  1070.  *-----------------------------------------------------------------------
  1071.  * CmpPdevID --
  1072.  *    Callback function for EstablishNewConnections to find the
  1073.  *    ClntStreamRec for an old pdev ID.
  1074.  *
  1075.  * Results:
  1076.  *    0 if the pdevID of the ClntStreamPtr matches the given pdevID
  1077.  *    and non-zero otherwise.
  1078.  *
  1079.  * Side Effects:
  1080.  *    None.
  1081.  *
  1082.  *-----------------------------------------------------------------------
  1083.  */
  1084. static int
  1085. CmpPdevID (pStream, pdevID)
  1086.     ClntStreamPtr pStream;
  1087.     int              pdevID;
  1088. {
  1089.     return (pStream->pdevID - pdevID);
  1090. }
  1091.  
  1092. /*-
  1093.  *-----------------------------------------------------------------------
  1094.  * ConnFail --
  1095.  *    Inform a client that it has been denied access.
  1096.  *
  1097.  * Results:
  1098.  *    None.
  1099.  *
  1100.  * Side Effects:
  1101.  *    None.
  1102.  *
  1103.  *-----------------------------------------------------------------------
  1104.  */
  1105. static void
  1106. ConnFail (streamID, swapped)
  1107.     int                  streamID;   /* ID of failing stream */
  1108.     Bool              swapped;    /* TRUE if client is byte-swapped */
  1109. {
  1110.     int                  *selMask;   /* Mask for selecting on stream */
  1111.     SpriteTime          timeout;    /* Timeout for select */
  1112.     int                  numReady;   /* Number of ready streams from select */
  1113.     int                  numBytes;   /* Number of bytes read/written */
  1114.     Pdev_Request    req;        /* Request from client */
  1115.     Pdev_Reply      reply;        /* Reply for bad request */
  1116.     struct {
  1117.     Pdev_Reply          reply;
  1118.     xConnSetupPrefix    c;
  1119.     }                   fail;        /* Reply to read request */
  1120.     
  1121.     Bit_Alloc (streamID+1, selMask);
  1122.     Bit_Set (streamID, selMask);
  1123.     timeout.seconds = REASONABLE_TIME;
  1124.     timeout.microseconds = 0;
  1125.     
  1126.     fail.reply.magic = reply.magic = PDEV_REPLY_MAGIC;
  1127.     fail.reply.selectBits = reply.selectBits = 0;
  1128.  
  1129.     if ((Fs_Select (streamID+1, &timeout, selMask, (int *)0,
  1130.             (int *)0, &numReady) != SUCCESS) ||
  1131.     (numReady != 1)) {
  1132.         ErrorF ("ConnFail: didn't read in a reasonable time\n");
  1133.         Bit_Free (selMask);
  1134.         return;
  1135.     }
  1136.     Bit_Free (selMask);
  1137.  
  1138.     (void) Fs_Read (streamID, sizeof(req), &req, &numBytes);
  1139.     if (req.operation != PDEV_READ) {
  1140.     reply.status = FS_DEVICE_OP_INVALID;
  1141.     reply.replySize = 0;
  1142.     (void) Fs_Write (streamID, sizeof(reply), &reply, &numBytes);
  1143.     ErrorF ("ConnFail: Didn't get a READ operation\n");
  1144.     return;
  1145.     }
  1146.  
  1147.     fail.c.success = xFalse;
  1148.     if (!swapped) {
  1149.     fail.c.length = 0;
  1150.     fail.c.majorVersion = X_PROTOCOL;
  1151.     fail.c.minorVersion = X_PROTOCOL_REVISION;
  1152.     } else {
  1153.     fail.c.length = lswaps(0);
  1154.     fail.c.majorVersion = lswaps(X_PROTOCOL);
  1155.     fail.c.minorVersion = lswaps(X_PROTOCOL_REVISION);
  1156.     }
  1157.     
  1158.     fail.reply.status = SUCCESS;
  1159.     fail.reply.replySize = sizeof(fail.c);
  1160.     (void) Fs_Write(streamID, sizeof(fail), &fail, &numBytes);
  1161. }
  1162.  
  1163.     
  1164. /*-
  1165.  *-----------------------------------------------------------------------
  1166.  * EstablishNewConnections --
  1167.  *    Accept connections from a new clients. If the request on the
  1168.  *    control stream is just a duplication of another stream,
  1169.  *    the new stream is added to the private data of the same
  1170.  *    client (this is what the StreamToClient map is used for) and
  1171.  *    no new client is created.
  1172.  *
  1173.  * Results:
  1174.  *    None returned. pNewClients and *pNumNew are filled in.
  1175.  *
  1176.  * Side Effects:
  1177.  *    AllClientsMask and AllStreamsMask are altered. Fields in the
  1178.  *    private structure for the new clients are filled in and the
  1179.  *    clients's connections marked active.
  1180.  *
  1181.  *-----------------------------------------------------------------------
  1182.  */
  1183. void
  1184. EstablishNewConnections (pNewClients, pNumNew)
  1185.     ClientPtr        *pNewClients;    /* Array to fill in */
  1186.     int              *pNumNew;     /* Number of new connections established */
  1187. {
  1188.     Bool          swapped;      /* True if data from client s/b swapped */
  1189.     Pdev_Request  pdev;        /* Notification from client */
  1190.     int              numRead;      /* Junk number of chars read */
  1191.     ClientPtr        client;     /* Client record for new client */
  1192.     ClntPrivPtr      pPriv;        /* Our private data for the client */
  1193.     ReturnStatus  rstat;        /* Syscall return status */
  1194.     ClntStreamPtr pStream;      /* Stream descriptor for new stream */
  1195.     Pdev_Notify   note;            /* Notification from control stream */
  1196.     register int  newID;
  1197.     register int  i;
  1198.     Pdev_Reply       reply;
  1199.     int              numWritten;
  1200.  
  1201.     *pNumNew = 0;
  1202.     
  1203.     reply.magic = PDEV_REPLY_MAGIC;
  1204.     reply.selectBits = FS_WRITABLE | FS_READABLE;
  1205.  
  1206.     while (1) {
  1207.     /*
  1208.      * Read requests from the control stream until there
  1209.      * are no more to read. The stream is non-blocking, so no need
  1210.      * to Fs_Select.
  1211.      */
  1212.     if (Fs_Read(PseudoDevice, sizeof (note), ¬e, &numRead) != SUCCESS){
  1213.         return;
  1214.     }
  1215.     if (note.magic != PDEV_NOTIFY_MAGIC) {
  1216.         continue;
  1217.     }
  1218.     newID = note.newStreamID;
  1219.  
  1220.     if ((Fs_Read (newID, sizeof(pdev), &pdev, &numRead) != SUCCESS) ||
  1221.         (pdev.magic != PDEV_REQUEST_MAGIC)) {
  1222.         Fs_Close (newID);
  1223.         continue;
  1224.     }
  1225.  
  1226.     if (pdev.operation == PDEV_OPEN) {
  1227.         if (!ClientAuthorized (newID, &swapped,
  1228.                    pdev.param.open.uid,
  1229.                    pdev.param.open.hostID)) {
  1230.                        ErrorF ("Unauthorized connection\n");
  1231.                        ConnFail (newID, swapped);
  1232.                        Fs_Close (newID);
  1233.                        continue;
  1234.         }
  1235.         client = NextAvailableClient();
  1236.         if (client == NullClient) {
  1237.         /*
  1238.          * If we can't get an ID for this client, we won't get one
  1239.          * for any other ones, but we have to acknowledge their
  1240.          * device opens so they don't hang forever in later writes.
  1241.          * Hence, we continue the loop rather than break out of it.
  1242.          */
  1243.         ErrorF ("No more clients!\n");
  1244.         ConnFail (newID, swapped);
  1245.         Fs_Close (newID);
  1246.         continue;
  1247.         }
  1248.         
  1249.         pPriv = (ClntPrivPtr) Mem_Alloc (sizeof(ClntPrivRec));
  1250.         client->osPrivate = (pointer) pPriv;
  1251.         client->swapped = swapped;
  1252.         
  1253.         pPriv->streams = Lst_Init (TRUE);
  1254.         pPriv->outBuf = Buf_Init (0);
  1255.  
  1256.         ErrorF ("New connection: client %d (newID = %d)\n", client->index,
  1257.             newID);
  1258.         pStream = (ClntStreamPtr) Mem_Alloc (sizeof(ClntStreamRec));
  1259.         pStream->streamID = newID;
  1260.         pStream->clientFlags = pdev.param.open.flags;
  1261.  
  1262.         (void) Lst_AtEnd (pPriv->streams, (ClientData)pStream);
  1263.         pPriv->lastStream = Lst_First(pPriv->streams);
  1264.         
  1265.         pPriv->ready = pPriv->mask = (int *)0;
  1266.         pPriv->maskWidth = 0;
  1267.         
  1268.         *pNewClients = client;
  1269.         pNewClients++;
  1270.         (*pNumNew)++;
  1271.     } else if (pdev.operation == PDEV_DUP) {
  1272.         ClntStreamPtr    pOldStream;
  1273.         LstNode            ln;
  1274.         
  1275.         reply.status = SUCCESS;
  1276.         reply.replySize = 0;
  1277.         (void) Fs_Write (newID, sizeof(reply), &reply, &numWritten);
  1278.         
  1279.         ln = Lst_Find (allStreams, (ClientData)pdev.param.open.clientID,
  1280.                CmpPdevID);
  1281.         pOldStream = (ClntStreamPtr) Lst_Datum (ln);
  1282.         client = pOldStream->client;
  1283.         ErrorF ("Duplicating stream for client %d (newID = %d)\n",
  1284.             client->index, newID);
  1285.         
  1286.         pStream = (ClntStreamPtr) Mem_Alloc (sizeof(ClntStreamRec));
  1287.         pStream->streamID = newID;
  1288.         pStream->clientFlags = pOldStream->clientFlags;
  1289.         pPriv = (ClntPrivPtr) client->osPrivate;
  1290.         (void) Lst_AtEnd (pPriv->streams, (ClientData)pStream);
  1291.     } else {
  1292.         continue;
  1293.     }
  1294.  
  1295.     /*
  1296.      * Common code for both duplication and connection. 
  1297.      */
  1298.     pStream->client = client;
  1299.     pStream->pdevID = pdev.param.open.clientID;
  1300.     pStream->buffer = (Address)NULL;
  1301.     pStream->numBytes = 0;
  1302.     pStream->needData = TRUE;
  1303.     
  1304.     ExpandMasks (client, newID);
  1305.     
  1306.     Ioc_SetBits (newID, IOC_NON_BLOCKING);
  1307.  
  1308.     (void) Lst_AtEnd (allStreams, (ClientData)pStream);
  1309.     
  1310.     /*
  1311.      * If we're only listening to one client, add the new client's
  1312.      * stream to the saved AllClients and AllStreams masks so it is
  1313.      * included when the grab is released. Otherwise, we can just
  1314.      * add the stream to the regular AllClients and AllStreams
  1315.      * masks.
  1316.      */
  1317.     if (GrabDone) {
  1318.         Bit_Set (newID, SavedAllClientsMask);
  1319.         Bit_Set (newID, SavedAllStreamsMask);
  1320.         if (client == grabbingClient) {
  1321.         Bit_Set (newID, AllClientsMask);
  1322.         Bit_Set (newID, AllStreamsMask);
  1323.         }
  1324.     } else {
  1325.         Bit_Set (newID, AllClientsMask);
  1326.         Bit_Set (newID, AllStreamsMask);
  1327.     }
  1328.     }
  1329. }
  1330.     
  1331. /*-
  1332.  *-----------------------------------------------------------------------
  1333. a132 1
  1334.     register ClntStreamPtr  pStream;
  1335. d138 1
  1336. a138 1
  1337.     Lst_ForEach (pPriv->streams, ConnectionClosed, (ClientData)0);
  1338. a141 2
  1339.     Lst_Destroy (pPriv->streams, NOFREE);
  1340.     Buf_Destroy (pPriv->outBuf, TRUE);
  1341. d144 1
  1342. d269 117
  1343. @
  1344.  
  1345.  
  1346. 1.11
  1347. log
  1348. @Confused Lst_Prev for Lst_Pred...
  1349. @
  1350. text
  1351. @d19 1
  1352. a19 1
  1353. "$Header: connect.c,v 1.10 87/08/21 20:29:27 deboor Exp $ SPRITE (Berkeley)";
  1354. d188 1
  1355. d249 1
  1356. d503 1
  1357. d574 1
  1358. a574 1
  1359.     Pdev_Reply    reply;
  1360. d580 1
  1361. a675 1
  1362.     pStream->waiting = FALSE;
  1363. @
  1364.  
  1365.  
  1366. 1.10
  1367. log
  1368. @Fixed problem with closing the most-recently-ready stream
  1369. @
  1370. text
  1371. @d19 1
  1372. a19 1
  1373. "$Header: connect.c,v 1.9 87/07/07 18:16:52 deboor Exp $ SPRITE (Berkeley)";
  1374. d410 1
  1375. a410 1
  1376.      * (Note that since the streams list is circular, Lst_Prev will always
  1377. d414 1
  1378. a414 1
  1379.     pPriv->lastStream = Lst_Prev(ln);
  1380. @
  1381.  
  1382.  
  1383. 1.9
  1384. log
  1385. @???
  1386. @
  1387. text
  1388. @d19 1
  1389. a19 1
  1390. "$Header: connect.c,v 1.8 87/06/30 19:12:25 deboor Exp $ SPRITE (Berkeley)";
  1391. d32 1
  1392. a32 1
  1393. #define    DEVICE_TEMPLATE    "/dev/%s/X11%s"
  1394. d65 1
  1395. a67 6
  1396. #ifdef not_yet
  1397.     Io_PrintString (errorfile, "/admin/X%smsgs", display);
  1398.     Io_Close (io_StdErr);
  1399.     io_StdErr = Io_Open (errorfile, "w+");
  1400. #endif not_yet
  1401.  
  1402. d72 2
  1403. a73 1
  1404.     Sys_GetHostName (hostname, sizeof(hostname));
  1405. d84 4
  1406. d120 3
  1407. d400 16
  1408. a424 1
  1409.     Buf_Destroy (pStream->outBuf, TRUE);
  1410. d626 1
  1411. d628 2
  1412. d655 2
  1413. a656 1
  1414.         ErrorF ("Duplicating stream for client %d\n", client->index);
  1415. a671 1
  1416.     pStream->outBuf = Buf_Init (0);
  1417. d737 1
  1418. a739 21
  1419. #ifdef notdef
  1420. /*-
  1421.  *-----------------------------------------------------------------------
  1422.  * ReallyMarkConnectionClosed --
  1423.  *    There doesn't seem to be any difference between marking a
  1424.  *    connection closed and Really marking it closed in the BSD library,
  1425.  *    so I'm not going to do anything special, here.
  1426.  *
  1427.  * Results:
  1428.  *    None.
  1429.  *
  1430.  * Side Effects:
  1431.  *    None.
  1432.  *
  1433.  *-----------------------------------------------------------------------
  1434.  */
  1435. ReallyMarkConnectionClosed (client)
  1436.     int        client;
  1437. {
  1438. }
  1439. #endif notdef
  1440. @
  1441.  
  1442.  
  1443. 1.8
  1444. log
  1445. @Adapted to beta-1
  1446. @
  1447. text
  1448. @d19 1
  1449. a19 1
  1450. "$Header: connect.c,v 1.7 87/06/24 12:51:17 deboor Exp $ SPRITE (Berkeley)";
  1451. d158 1
  1452. a158 1
  1453.         if (stat_LastStatus == SUCCESS) {
  1454. d161 1
  1455. a161 1
  1456.         return (stat_LastStatus);
  1457. @
  1458.  
  1459.  
  1460. 1.7
  1461. log
  1462. @Adapted to new Dup mechanism
  1463. @
  1464. text
  1465. @d19 1
  1466. a19 1
  1467. "$Header: connect.c,v 1.6 87/06/23 13:30:21 deboor Exp $ SPRITE (Berkeley)";
  1468. d28 3
  1469. a30 3
  1470.  * This should look like
  1471.  *    /<hostname>/X<display-number>
  1472.  * but the machines don't have local /hostname systems yet...
  1473. d32 1
  1474. a32 1
  1475. #define    DEVICE_NAME    "/tmp/X11"
  1476. d59 1
  1477. a59 1
  1478.     char          deviceName[50];   /* Path to pseudo-device */
  1479. d65 1
  1480. d77 2
  1481. a78 1
  1482.     Io_PrintString (deviceName, "%s%s", DEVICE_NAME, display);
  1483. d144 2
  1484. a145 2
  1485.     Fs_PdevRequest    pdev;
  1486.     Fs_PdevEasyReply    reply;
  1487. d169 1
  1488. a169 1
  1489.     if (pdev.magic != FS_PDEV_REQUEST_MAGIC) {
  1490. d173 1
  1491. a173 1
  1492.     if (pdev.operation != FS_PDEV_WRITE) {
  1493. d185 1
  1494. a185 1
  1495.     reply.magic = FS_PDEV_REPLY_MAGIC;
  1496. d236 1
  1497. a236 1
  1498.     Fs_PdevReply      openRep;    /* Reply to OPEN request */
  1499. d243 1
  1500. a243 1
  1501.     openRep.magic = FS_PDEV_REPLY_MAGIC;
  1502. d281 3
  1503. a283 2
  1504.     if (ReadConn(conn, selMask, xccp.nbytesAuthProto, authProto) != SUCCESS){
  1505.         return (0);
  1506. d295 3
  1507. a297 2
  1508.     if (ReadConn(conn, selMask, xccp.nbytesAuthString, authString)!=SUCCESS){
  1509.         return (0);
  1510. d321 5
  1511. a325 5
  1512. ExpandMasks (clientID, newStream)
  1513.     int        clientID;        /* The client for which the stream was opened.
  1514.                  * Should be 0 if it wasn't opened for a client
  1515.                  * (e.g. it's for a device) */
  1516.     int        newStream;        /* The new stream's ID number */
  1517. d327 1
  1518. a327 1
  1519.     ClntPrivPtr      pPriv = &clientPriv[clientID];
  1520. d353 1
  1521. a353 1
  1522.     if (clientID > 0) {
  1523. d390 1
  1524. a390 1
  1525.     ErrorF ("ConnectionClosed: client %d, stream %d\n", pStream->clientID,
  1526. d394 1
  1527. a394 1
  1528.     pPriv = &clientPriv[pStream->clientID];
  1529. d397 3
  1530. a399 1
  1531.     Lst_Remove (pPriv->streams, ln);
  1532. d402 3
  1533. a404 1
  1534.     Lst_Remove (allStreams, ln);
  1535. d470 2
  1536. a471 2
  1537.     Fs_PdevRequest    req;        /* Request from client */
  1538.     Fs_PdevReply      reply;        /* Reply for bad request */
  1539. d473 1
  1540. a473 1
  1541.     Fs_PdevReply          reply;
  1542. d482 1
  1543. a482 1
  1544.     fail.reply.magic = reply.magic = FS_PDEV_REPLY_MAGIC;
  1545. d494 1
  1546. a494 1
  1547.     if (req.operation != FS_PDEV_READ) {
  1548. d540 1
  1549. a540 1
  1550.     NewClientPtr  pNewClients;    /* Array to fill in */
  1551. d544 1
  1552. a544 1
  1553.     Fs_PdevRequest pdev;        /* Notification from client */
  1554. d546 1
  1555. a546 1
  1556.     int              clientID;     /* Client number for new client */
  1557. d549 2
  1558. a550 2
  1559.     ClntStreamPtr pStream;
  1560.     Fs_PdevNotify note;            /* Notification from control stream */
  1561. d553 1
  1562. a553 1
  1563.     Fs_PdevReply  reply;
  1564. a554 1
  1565.     int              fsBits = IOC_NON_BLOCKING;
  1566. d558 1
  1567. a558 1
  1568.     reply.magic = FS_PDEV_REPLY_MAGIC;
  1569. d569 1
  1570. a569 1
  1571.     if (note.magic != FS_PDEV_NOTIFY_MAGIC) {
  1572. d575 1
  1573. a575 1
  1574.         (pdev.magic != FS_PDEV_REQUEST_MAGIC)) {
  1575. d580 1
  1576. a580 1
  1577.     if (pdev.operation == FS_PDEV_OPEN) {
  1578. d589 2
  1579. a590 2
  1580.         clientID = NextAvailableClientID();
  1581.         if (clientID == -1) {
  1582. d603 4
  1583. a606 1
  1584.         pPriv = (ClntPrivPtr) &clientPriv[clientID];
  1585. d619 1
  1586. a619 2
  1587.         pNewClients->id = clientID;
  1588.         pNewClients->swapped = swapped;
  1589. d622 1
  1590. a622 4
  1591.         if (clientID > LastClient) {
  1592.         LastClient = clientID;
  1593.         }
  1594.     } else if (pdev.operation == FS_PDEV_DUP) {
  1595. d633 2
  1596. a634 2
  1597.         clientID = pOldStream->clientID;
  1598.         ErrorF ("Duplicating stream for client %d\n", clientID);
  1599. d639 1
  1600. a639 1
  1601.         pPriv = &clientPriv[clientID];
  1602. d648 1
  1603. a648 1
  1604.     pStream->clientID = clientID;
  1605. d656 1
  1606. a656 1
  1607.     ExpandMasks (clientID, newID);
  1608. d658 1
  1609. a658 1
  1610.     IOC_SetBits (newID, fsBits);
  1611. d672 1
  1612. a672 1
  1613.         if (clientID == grabbingClientID) {
  1614. d699 2
  1615. a700 2
  1616. CloseDownConnection (clientID)
  1617.     int        clientID;            /* Client number whose connection should
  1618. d707 1
  1619. a707 1
  1620.     pPriv = &clientPriv[clientID];
  1621. d709 2
  1622. a714 1
  1623.     pPriv->ready = (int *)0;
  1624. d716 1
  1625. d718 1
  1626. a718 1
  1627.  
  1628. d738 1
  1629. a738 1
  1630.  
  1631. d805 2
  1632. a806 2
  1633. OnlyListenToOneClient (clientID)
  1634.     int        clientID;
  1635. d808 1
  1636. a808 1
  1637.     ClntPrivPtr      pPriv = &clientPriv[clientID];
  1638. d822 1
  1639. a822 1
  1640.     ErrorF("Server grabbed by client %d\n", clientID);
  1641. d839 1
  1642. a839 1
  1643.     grabbingClientID = clientID;
  1644. @
  1645.  
  1646.  
  1647. 1.6
  1648. log
  1649. @Adapted to Buf library usage
  1650. @
  1651. text
  1652. @d19 1
  1653. a19 1
  1654. "$Header: connect.c,v 1.5 87/06/20 19:58:07 deboor Exp $ SPRITE (Berkeley)";
  1655. a342 2
  1656.     StreamToClient = (int *)Xrealloc (StreamToClient,
  1657.                       NumActiveStreams * sizeof(int));
  1658. a358 4
  1659.     /*
  1660.      * Finally, we add the streamID to clientID translation to our table.
  1661.      */
  1662.     StreamToClient[newStream] = clientID;
  1663. d394 4
  1664. d419 1
  1665. a419 1
  1666.  * CmpStreamID --
  1667. d421 1
  1668. a421 1
  1669.  *    ClntStreamRec for an old streamID.
  1670. d424 1
  1671. a424 1
  1672.  *    0 if the streamID of the ClntStreamPtr matches the given streamID
  1673. d433 1
  1674. a433 1
  1675. CmpStreamID (pStream, streamID)
  1676. d435 1
  1677. a435 1
  1678.     int              streamID;
  1679. d437 1
  1680. a437 1
  1681.     return (pStream->streamID - streamID);
  1682. a619 3
  1683.         clientID = StreamToClient[pdev.param.dup.oldStreamID];
  1684.         
  1685.         ErrorF ("Duplicating stream for client %d\n", clientID);
  1686. d624 2
  1687. a625 2
  1688.         ln = Lst_Find (pPriv->streams, pdev.param.dup.oldStreamID,
  1689.                CmpStreamID);
  1690. d627 2
  1691. d633 2
  1692. d643 1
  1693. d653 2
  1694. @
  1695.  
  1696.  
  1697. 1.5
  1698. log
  1699. @adapted to Beta-0 and "debugged"
  1700. @
  1701. text
  1702. @d19 1
  1703. a19 1
  1704. "$Header: connect.c,v 1.4 87/06/16 12:22:57 deboor Exp $ SPRITE (Berkeley)";
  1705. d400 1
  1706. a400 1
  1707.     Lst_Destroy (pStream->outPackets, Mem_Free);
  1708. d549 1
  1709. d644 1
  1710. a644 2
  1711.     pStream->outPackets = Lst_Init (FALSE);
  1712.     pStream->lenPackets = 0;
  1713. d651 2
  1714. @
  1715.  
  1716.  
  1717. 1.4
  1718. log
  1719. @Adapted to new protocol?
  1720. @
  1721. text
  1722. @d19 1
  1723. a19 1
  1724. "$Header: connect.c,v 1.3 87/06/13 11:21:46 deboor Exp $ SPRITE (Berkeley)";
  1725. d255 1
  1726. d392 2
  1727. d404 2
  1728. d490 1
  1729. a490 1
  1730.     reply.replySize;
  1731. d623 1
  1732. d648 1
  1733. d796 2
  1734. a797 1
  1735.     ClntPrivPtr      pPriv;
  1736. d801 3
  1737. d805 3
  1738. a807 1
  1739.     (void) Bit_Intersect (NumActiveStreams, pPriv->mask,
  1740. d810 1
  1741. d821 1
  1742. a821 1
  1743.     (void) Bit_Union (NumActiveStreams, pPriv->mask, EnabledDevicesMask,
  1744. d824 1
  1745. d847 1
  1746. @
  1747.  
  1748.  
  1749. 1.3
  1750. log
  1751. @Altered connection protocol to account for new Pdev protocol
  1752. @
  1753. text
  1754. @d19 1
  1755. a19 1
  1756. "$Header: connect.c,v 1.2 87/06/11 18:41:34 deboor Exp $ SPRITE (Berkeley)";
  1757. d59 1
  1758. d76 1
  1759. d78 1
  1760. a78 1
  1761.         (Fs_Open (DEVICE_NAME,
  1762. d82 1
  1763. d84 1
  1764. a84 1
  1765.                   DEVICE_NAME);
  1766. d122 75
  1767. a232 1
  1768.     int                  numRead;    /* Number of bytes read last time */
  1769. d234 1
  1770. a234 4
  1771.     Fs_PdevRequest    pdev;        /* The PDEV_WRITE request */
  1772.     Fs_PdevEasyReply    writeRep;   /* Reply to said write request */
  1773.     SpriteTime          timeout;    /* Timeout for selection */
  1774.     int                  numWritten; /* Number of bytes written in Fs_Write */
  1775. d236 1
  1776. a236 1
  1777.     int                  numReady;   /* Number of ready streams (from select) */
  1778. d239 8
  1779. a251 15
  1780.     Bit_Set (conn, selMask);
  1781.     timeout.seconds = REASONABLE_TIME;
  1782.     timeout.microseconds = 0;
  1783.     
  1784.     if ((Fs_Select (conn+1, &timeout, selMask, (int *)0,
  1785.             (int *)0, &numReady) != SUCCESS) ||
  1786.     (numReady != 1)) {
  1787.         Bit_Free (selMask);
  1788.         return (0);
  1789.     }
  1790.     if ((Fs_Read (conn, sizeof(pdev), &pdev, &numRead) != SUCCESS) ||
  1791.     (pdev.magic != FS_PDEV_REQUEST_MAGIC) ||
  1792.     (pdev.operation != FS_PDEV_WRITE)) {
  1793.         return (0);
  1794.     }
  1795. d253 2
  1796. a254 10
  1797.     /*
  1798.      * However many bytes the client wrote, we will read them all (or we'll
  1799.      * close down the connection...)
  1800.      */
  1801.     writeRep.replySize = 0;
  1802.     writeRep.data = pdev.requestSize;
  1803.     writeRep.status = SUCCESS;
  1804.     writeRep.magic = FS_PDEV_REPLY_MAGIC;
  1805.     if (Fs_Write (conn, sizeof(writeRep), &writeRep, &numWritten) != SUCCESS) {
  1806.     return (0);
  1807. a256 7
  1808.     if ((Fs_Read (conn, sizeof(xccp), &xccp, &numRead) != SUCCESS) ||
  1809.     (numRead != sizeof(xccp))){
  1810.         return (0);
  1811.     }
  1812.  
  1813.     pdev.requestSize -= numRead;
  1814.     
  1815. d274 2
  1816. a275 3
  1817.     if ((xccp.nbytesAuthProto != 0) &&
  1818.     (pdev.requestSize >= xccp.nbytesAuthProto)) {
  1819.         char      *authProto;
  1820. d277 5
  1821. a281 7
  1822.         authProto = (char *)ALLOCATE_LOCAL(xccp.nbytesAuthProto);
  1823.         if (Fs_Read (conn, xccp.nbytesAuthProto,
  1824.              authProto, &numRead) != SUCCESS) {
  1825.                  return (0);
  1826.         }
  1827.         pdev.requestSize -= numRead;
  1828.         DEALLOCATE_LOCAL (authProto);
  1829. d287 2
  1830. a288 3
  1831.     if ((xccp.nbytesAuthString != 0) &&
  1832.     (pdev.requestSize >= xccp.nbytesAuthString)) {
  1833.         char      *authString;
  1834. d290 5
  1835. a294 7
  1836.         authString = (char *)ALLOCATE_LOCAL(xccp.nbytesAuthString);
  1837.         if (Fs_Read (conn, xccp.nbytesAuthString,
  1838.              authString, &numRead) != SUCCESS) {
  1839.                  return (0);
  1840.         }
  1841.         pdev.requestSize -= numRead;
  1842.         DEALLOCATE_LOCAL (authString);
  1843. d297 1
  1844. a297 9
  1845.     /*
  1846.      * If there were extra bytes sent, we fail (the principle of the
  1847.      * thing)
  1848.      */
  1849.     if (pdev.requestSize != 0) {
  1850.     return (0);
  1851.     } else {
  1852.     return (1);
  1853.     }
  1854. d439 71
  1855. d555 1
  1856. a555 1
  1857.     if ((Fs_Read(PseudoDevice, sizeof (note), ¬e, &numRead) != SUCCESS){
  1858. d574 1
  1859. a574 5
  1860.                        reply.status = FS_NO_ACCESS;
  1861.                        reply.replySize = 0;
  1862.                        (void) Fs_Write (newID,
  1863.                             sizeof(reply),
  1864.                             &reply, &numWritten);
  1865. d587 1
  1866. a587 4
  1867.         reply.status = FAILURE;
  1868.         reply.replySize = 0;
  1869.         (void) Fs_Write (newID, sizeof(reply), &reply,
  1870.                  &numWritten);
  1871. @
  1872.  
  1873.  
  1874. 1.2
  1875. log
  1876. @Converted to use Bit_Expand
  1877. @
  1878. text
  1879. @d19 1
  1880. a19 1
  1881. "$Header: connect.c,v 1.1 87/06/11 17:47:03 deboor Exp $ SPRITE (Berkeley)";
  1882. d30 1
  1883. a30 1
  1884.  * but there's no way to get the hostname in Sprite, yet...
  1885. a34 2
  1886. #define INIT_NUM_STREAMS    2
  1887. #define INC_NUM_STREAMS        2
  1888. a35 6
  1889. /*
  1890.  * IOControls supported by the server. These definitions should be copied
  1891.  * to the Xlibos.h file in the sprite Xlib directory.
  1892.  */
  1893. #define IOC_X_NUM_READABLE  0x80000001
  1894.  
  1895. d150 4
  1896. a153 4
  1897.     int        conn;     /* Stream of connection */
  1898.     Bool    *pswapped;    /* Set TRUE if client is byte-swapped */
  1899.     int        uid;
  1900.     int        hostid;
  1901. d155 8
  1902. a162 9
  1903.     int                  lastRead;
  1904.     int                  totRead;
  1905.     xConnClientPrefix     xccp;
  1906.     Fs_PdevRequest    pdev;
  1907.     Fs_PdevEasyReply    writeRep;
  1908.     SpriteTime          timeout;
  1909.     int                  numWritten;
  1910.     int                  *selMask;
  1911.     int                  numReady;
  1912. d180 4
  1913. a183 2
  1914.     if (Fs_Read (conn, sizeof(pdev), &pdev, &lastRead) != SUCCESS) {
  1915.     return (0);
  1916. a184 1
  1917.     totRead = 0;
  1918. d186 4
  1919. d193 4
  1920. a196 1
  1921.     Fs_Write (conn, sizeof(writeRep), &writeRep, &numWritten);
  1922. d198 2
  1923. a199 2
  1924.     if ((Fs_Read (conn, sizeof(xccp), &xccp, &lastRead) != SUCCESS) ||
  1925.     (lastRead != sizeof(xccp))){
  1926. d203 1
  1927. a203 2
  1928.     pdev.requestSize -= lastRead;
  1929.     totRead += lastRead;
  1930. d225 1
  1931. d228 1
  1932. a228 1
  1933.              authProto, &lastRead) != SUCCESS) {
  1934. d231 1
  1935. a231 2
  1936.         pdev.requestSize -= lastRead;
  1937.         totRead += lastRead;
  1938. d241 1
  1939. d244 1
  1940. a244 1
  1941.              authString, &lastRead) != SUCCESS) {
  1942. d247 1
  1943. a247 2
  1944.         totRead += lastRead;
  1945.         pdev.requestSize -= lastRead;
  1946. d279 4
  1947. a282 2
  1948.     int        clientID;
  1949.     int        newStream;
  1950. d310 1
  1951. a310 2
  1952.      * encompass the new stream. Again, we only reallocate if the
  1953.      * mask will really be bigger.
  1954. d337 1
  1955. a337 1
  1956.  *    None.
  1957. d340 2
  1958. a341 1
  1959.  *    The client is terminated.
  1960. d345 1
  1961. a345 1
  1962. void
  1963. d347 1
  1964. a347 1
  1965.     ClntStreamPtr         pStream;        /* The stream to close */
  1966. d349 3
  1967. a351 2
  1968.     register int          i;
  1969.     register ClntPrivPtr    pPriv;
  1970. a352 2
  1971.     Io_Close (pStream->inStream);
  1972.     Io_Close (pStream->outStream);
  1973. a353 1
  1974.     pStream->active = FALSE;
  1975. d356 6
  1976. a361 4
  1977.     for (i = pPriv->numStreams; i; i--) {
  1978.     if (pPriv->streams[i-1].active) {
  1979.         break;
  1980.     }
  1981. d363 7
  1982. a369 2
  1983.     if (i == 0) {
  1984.     CloseDownClient (clients[pStream->clientID]);
  1985. d371 3
  1986. d378 3
  1987. a380 3
  1988.  * HandleIOControl --
  1989.  *    Some client has performed some IOControl on the request-response
  1990.  *    stream.
  1991. d383 2
  1992. a384 1
  1993.  *    None.
  1994. d387 1
  1995. a387 2
  1996.  *    The response to the IOControl is written as a reply on the private
  1997.  *    stream.
  1998. d391 4
  1999. a394 7
  2000. static void
  2001. HandleIOControl (streamID, command, inBufSize, inBufPtr, pStream)
  2002.     int              streamID;     /* Request/response stream */
  2003.     int              command;      /* Command from client */
  2004.     int              inBufSize;    /* Size of input buffer */
  2005.     Address       inBufPtr;     /* Input buffer */
  2006.     ClntStreamPtr pStream;      /* Real stream structure */
  2007. d396 1
  2008. a396 23
  2009.     int              numWritten;
  2010.  
  2011.     switch (command) {
  2012.     case IOC_X_NUM_READABLE: {
  2013.         Fs_PdevEasyReply    reply;
  2014.  
  2015.         reply.status = SUCCESS;
  2016.         reply.replySize = sizeof(int);
  2017.         reply.data = pStream->outStream->lastAccess -
  2018.         pStream->outStream->buffer + 1;
  2019.  
  2020.         (void) Fs_Write (streamID, sizeof(reply), &reply, &numWritten);
  2021.         break;
  2022.     }
  2023.     default: {
  2024.         Fs_PdevReply        reply;
  2025.  
  2026.         reply.status = FS_DEVICE_OP_INVALID;
  2027.         reply.replySize = 0;
  2028.         (void) Fs_Write (streamID, sizeof(reply), &reply, &numWritten);
  2029.         break;
  2030.     }
  2031.     }
  2032. d430 2
  2033. a431 1
  2034.     int              newStreamID;    /* New stream ID to use */
  2035. d438 2
  2036. d446 1
  2037. a446 3
  2038.     rstat = Fs_Read (PseudoDevice, sizeof (newStreamID),
  2039.              &newStreamID, &numRead);
  2040.     if (rstat != SUCCESS) {
  2041. d449 1
  2042. a449 4
  2043.  
  2044.     rstat = Fs_Read (newStreamID, sizeof (pdev), &pdev, &numRead);
  2045.     if (rstat != SUCCESS) {
  2046.         Fs_Close (newStreamID);
  2047. d452 1
  2048. d454 6
  2049. d461 1
  2050. a461 1
  2051.         if (!ClientAuthorized (newStreamID, &swapped,
  2052. d467 1
  2053. a467 1
  2054.                        (void) Fs_Write (newStreamID,
  2055. d470 1
  2056. a470 1
  2057.                        Fs_Close (newStreamID);
  2058. d484 1
  2059. a484 1
  2060.         (void) Fs_Write (newStreamID, sizeof(reply), &reply,
  2061. d486 1
  2062. a486 1
  2063.         Fs_Close (newStreamID);
  2064. d491 4
  2065. a494 8
  2066.         pPriv->numStreams = INIT_NUM_STREAMS;
  2067.         pPriv->streams = (ClntStreamPtr)Xalloc (INIT_NUM_STREAMS *
  2068.                             sizeof(ClntStreamRec));
  2069.         for (i = 1; i < INIT_NUM_STREAMS; i++) {
  2070.         pPriv->streams[i].active = FALSE;
  2071.         }
  2072.         pStream = pPriv->streams;
  2073.         pStream->streamID = newStreamID;
  2074. d496 4
  2075. d512 1
  2076. d518 1
  2077. a518 1
  2078.         (void) Fs_Write (newStreamID, sizeof(reply), &reply, &numWritten);
  2079. d520 6
  2080. a525 36
  2081.         /*
  2082.          * Search the client's "streams" table for an open slot
  2083.          * in which to insert this new stream. If one is found,
  2084.          * "i" will be its index and will be less than
  2085.          * "pPriv->numStreams"
  2086.          */
  2087.         pPriv = &clientPriv[clientID];
  2088.         for (i = 0; i < pPriv->numStreams; i++) {
  2089.         if (!pPriv->streams[i].active) {
  2090.             break;
  2091.         } else if (pPriv->streams[i].streamID ==
  2092.                pdev.param.dup.oldStreamID){
  2093.                    pOldStream = &pPriv->streams[i];
  2094.         }
  2095.         }
  2096.         if (i == pPriv->numStreams) {
  2097.         /*
  2098.          * There was no more room in the streams table, so we
  2099.          * need to reallocate it to make room for this new
  2100.          * stream. The newly-allocate ClntStreamRec's are
  2101.          * all marked as inactive and i is set to the index of
  2102.          * the first one.
  2103.          */
  2104.         pPriv->numStreams += INC_NUM_STREAMS;
  2105.         pPriv->streams =
  2106.             (ClntStreamPtr) Xrealloc (pPriv->streams,
  2107.                           pPriv->numStreams *
  2108.                           sizeof (ClntStreamRec));
  2109.         while (i < pPriv->numStreams) {
  2110.             pPriv->streams[i].active = FALSE;
  2111.             i++;
  2112.         }
  2113.         i = pPriv->numStreams - INC_NUM_STREAMS;
  2114.         }
  2115.         pStream = &pPriv->streams[i];
  2116.         pStream->streamID = newStreamID;
  2117. d532 1
  2118. a532 2
  2119.      * Common code for both duplication and connection. Pdev_Init
  2120.      * is called to initialize the pseudo-device streams.
  2121. a533 1
  2122.     pStream->active = TRUE;
  2123. d535 5
  2124. a539 7
  2125.     Pdev_Init (pStream->streamID,
  2126.            FS_NON_BLOCKING,
  2127.            pStream->clientFlags,
  2128.            &pStream->inStream,
  2129.            &pStream->outStream,
  2130.            ConnectionClosed, pStream,
  2131.            HandleIOControl, pStream);
  2132. d541 1
  2133. a541 1
  2134.     ExpandMasks (clientID, pStream->streamID);
  2135. d551 2
  2136. a552 2
  2137.         Bit_Set (pStream->streamID, SavedAllClientsMask);
  2138.         Bit_Set (pStream->streamID, SavedAllStreamsMask);
  2139. d554 2
  2140. a555 2
  2141.         Bit_Set (pStream->streamID, AllClientsMask);
  2142.         Bit_Set (pStream->streamID, AllStreamsMask);
  2143. d558 2
  2144. a559 2
  2145.         Bit_Set (pStream->streamID, AllClientsMask);
  2146.         Bit_Set (pStream->streamID, AllStreamsMask);
  2147. d590 1
  2148. a590 16
  2149.     for (i = 0, pStream = &pPriv->streams[0];
  2150.      i < pPriv->numStreams;
  2151.      i++, pStream++) {
  2152.          if (pStream->active) {
  2153.          Io_Close (pStream->inStream);
  2154.          Io_Close (pStream->outStream);
  2155.          Fs_Close (pStream->streamID);
  2156.          if (GrabDone) {
  2157.              Bit_Clear (pStream->streamID, SavedAllStreamsMask);
  2158.              Bit_Clear (pStream->streamID, SavedAllClientsMask);
  2159.          } else {
  2160.              Bit_Clear (pStream->streamID, AllStreamsMask);
  2161.              Bit_Clear (pStream->streamID, AllClientsMask);
  2162.          }
  2163.          }
  2164.     }
  2165. d595 1
  2166. a595 2
  2167.     Xfree (pPriv->streams);
  2168.  
  2169. a687 1
  2170.     int              *tempMask;        /* Mask for streamIDs */
  2171. d692 1
  2172. a692 4
  2173.     Bit_Alloc (NumActiveStreams, tempMask);
  2174.     Bit_Copy (pPriv->maskWidth, pPriv->mask, tempMask);
  2175.     
  2176.     (void) Bit_Intersect (NumActiveStreams, tempMask,
  2177. d705 1
  2178. a705 1
  2179.     (void) Bit_Union (NumActiveStreams, tempMask, EnabledDevicesMask,
  2180. d707 1
  2181. a707 2
  2182.     Bit_Copy (NumActiveStreams, tempMask, AllClientsMask);
  2183.     Bit_Free (tempMask);
  2184. @
  2185.  
  2186.  
  2187. 1.1
  2188. log
  2189. @Initial revision
  2190. @
  2191. text
  2192. @d19 1
  2193. a19 1
  2194. "$Header$ SPRITE (Berkeley)";
  2195. d287 17
  2196. a303 48
  2197.     if (Bit_NumInts(newStream + 1) > Bit_NumInts(NumActiveStreams)) {
  2198.         /*
  2199.          * First we expand the size of the standard masks. Note this
  2200.          * is only done if the new masks will take up more space
  2201.          * (in longwords). This is to avoid reallocating too often.
  2202.          * It does, however, assume that the masks are allocated in
  2203.          * longword chunks.
  2204.          */
  2205.         register int newNumStreams = newStream + 1;
  2206.         register int *tempMask;
  2207.         
  2208.         Bit_Alloc (newNumStreams, tempMask);
  2209.         Bit_Copy  (newNumStreams, AllStreamsMask, tempMask);
  2210.         Bit_Free  (AllStreamsMask);
  2211.         AllStreamsMask =        tempMask;
  2212.         
  2213.         Bit_Alloc (newNumStreams, tempMask);
  2214.         Bit_Copy  (newNumStreams, LastSelectMask, tempMask);
  2215.         Bit_Free  (LastSelectMask);
  2216.         LastSelectMask =        tempMask;
  2217.         
  2218.         Bit_Alloc (newNumStreams, tempMask);
  2219.         Bit_Copy  (newNumStreams, EnabledDevicesMask, tempMask);
  2220.         Bit_Free  (EnabledDevicesMask);
  2221.         EnabledDevicesMask =    tempMask;
  2222.         
  2223.         Bit_Alloc (newNumStreams, tempMask);
  2224.         Bit_Copy  (newNumStreams, ClientsWithInputMask, tempMask);
  2225.         Bit_Free  (ClientsWithInputMask);
  2226.         ClientsWithInputMask =  tempMask;
  2227.         
  2228.         Bit_Alloc (newNumStreams, tempMask);
  2229.         Bit_Copy  (newNumStreams, AllClientsMask, tempMask);
  2230.         Bit_Free  (AllClientsMask);
  2231.         AllClientsMask =        tempMask;
  2232.         
  2233.         Bit_Alloc (newNumStreams, tempMask);
  2234.         Bit_Copy  (newNumStreams, SavedAllClientsMask, tempMask);
  2235.         Bit_Free  (SavedAllClientsMask);
  2236.         SavedAllClientsMask =   tempMask;
  2237.         
  2238.         Bit_Alloc (newNumStreams, tempMask);
  2239.         Bit_Copy  (newNumStreams, SavedAllStreamsMask, tempMask);
  2240.         Bit_Free  (SavedAllStreamsMask);
  2241.         SavedAllStreamsMask =   tempMask;
  2242.         
  2243.     }
  2244.     NumActiveStreams = newStream + 1;
  2245. d313 6
  2246. a318 17
  2247.     if ((clientID > 0) && (newStream >= pPriv->maskWidth)) {
  2248.     if (Bit_NumInts (newStream + 1) > Bit_NumInts (pPriv->maskWidth)) {
  2249.         int      *tempMask;
  2250.  
  2251.         Bit_Alloc (newStream + 1, tempMask);
  2252.         if (pPriv->mask) {
  2253.         Bit_Copy (pPriv->maskWidth, pPriv->mask, tempMask);
  2254.         Bit_Free (pPriv->mask);
  2255.         }
  2256.         pPriv->mask = tempMask;
  2257.  
  2258.         Bit_Alloc (newStream + 1, tempMask);
  2259.         if (pPriv->ready) {
  2260.         Bit_Copy (pPriv->maskWidth, pPriv->ready, tempMask);
  2261.         Bit_Free (pPriv->ready);
  2262.         }
  2263.         pPriv->ready = tempMask;
  2264. @
  2265.